# -*- coding: utf-8 -*-
#refs to: machine learning in action 14.2 chapter
import numpy as np


def standEst(dataMat,user,simMeas,item):
    n = np.shape(dataMat)[1]
    simTotal = 0.0
    ratSimTotal = 0.0
    for j in range(n):
        userRating = dataMat[user,j]
        if userRating == 0:
            continue
        overLap = np.nonzero(np.logical_and(dataMat[:,item].A > 0, dataMat[:,j].A >0))[0]
        if len(overLap) == 0:
            similarity = 0
        else:
            similarity = simMeas(dataMat[overLap,item], dataMat[overLap, j])
        simTotal += similarity
        ratSimTotal += similarity * userRating
    if simTotal == 0:
        return 0
    else:
        return ratSimTotal / simTotal

def ecludSim(inA,inB):
    return 1.0/(1.0 + np.linalg.norm(inA - inB))

def pearsSim(inA,inB):
    if len(inA) < 3:
        return 1.0
    return 0.5+0.5*np.corrcoef(inA,inB,rowvar=0)[0][1]

def cosSim(inA,inB):
    num = float(inA.T*inB)
    denom = np.linalg.norm(inA)*np.linalg.norm(inB)
    return 0.5+0.5*(num/denom)

def recommend(dataMat, user, N=3, simMeans=cosSim, estMethod=standEst):
    unratedItems = np.nonzero(dataMat[user,:].A == 0 )[1]
    if len(unratedItems)==0:
        return 'you rated everything'
    itemScores = []
    for item in unratedItems:
        estimatedScore = estMethod(dataMat, user, simMeans, item)
        itemScores.append((item,estimatedScore))
    return sorted(itemScores, key=lambda jj: jj[1],reverse=True)[:N]


if __name__ == '__main__':
    print("test")
    #col = item, row = user
    data = [
        [4,4,0,2,2],
        [4,0,0,3,3],
        [4,0,0,1,1],
        [1,1,1,2,0],
        [2,2,2,0,0],
        [1,1,1,0,0],
        [5,5,5,0,0]
    ]

    data = np.matrix(data)

    print(recommend(data,2))
    print(recommend(data,2,simMeans=ecludSim))
    print(recommend(data,2,simMeans=pearsSim))
